using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace Editor
{
    public class SideMenu
    {
        private const int N_RESIZE_SPEED = 4;

        private Viewport sideMenuViewport;
        private List<MenuItem> lstMenuItems = new List<MenuItem>();
        private Color cBackgroundColor = Color.Silver;
        private MapArea mapArea;
        private Dictionary<Type, Texture2D> dicMenuItemTextures = new Dictionary<Type, Texture2D>();

        private SideMenu MapObjectsSideMenu = null;
        private SideMenu ParentSideMenu = null;
        private MinimizeSideMenuBar minimizeSideMenuBar;
        
        private bool bMinimizing = false;
        private bool bMaxamizing = false;
        private bool bMinimized = false;
        private bool bHasFocus = false;

        public bool IsMinimizing
        {
            get
            {
                return this.bMinimizing;
            }
            set
            {
                this.bMinimizing = value;

                if (this.MapObjectsSideMenu != null)
                {
                    this.MapObjectsSideMenu.IsMinimizing = value;
                }
            }
        }
        public bool IsMaxamizing
        {
            get
            {
                return this.bMaxamizing;
            }
            set
            {
                this.bMaxamizing = value;

                if (this.MapObjectsSideMenu != null)
                {
                    this.MapObjectsSideMenu.IsMaxamizing = value;
                }
            }
        }
        public bool IsMinimized
        {
            get
            {
                return this.bMinimized;
            }
            set
            {
                this.bMinimized = value;
                if (this.MapObjectsSideMenu != null)
                {
                    this.MapObjectsSideMenu.IsMinimized = value;
                }
            }
        }
        public bool HasFocus
        {
            get
            {
                return this.bHasFocus;
            }
            set
            {
                this.bHasFocus = value;
                if (this.MapObjectsSideMenu != null)
                {
                    this.MapObjectsSideMenu.HasFocus = value;
                }
            }
        }

        public int Width
        {
            get
            {
                int nWidth = 0;
                foreach (MenuItem item in this.lstMenuItems)
                {
                    if (item.Width > nWidth)
                    {
                        nWidth = item.Width;
                    }
                }

                nWidth += this.minimizeSideMenuBar.Width;

                return nWidth;
            }
        }

        public int Height
        {
            get
            {
                return this.sideMenuViewport.Height;
            }
        }

        private Vector2 vBottomPositionOfMenuItems = Vector2.Zero;

        public SideMenu(MapArea mapArea, Dictionary<Type, Texture2D> menuItemTextures)
        {
            this.mapArea = mapArea;
            this.dicMenuItemTextures = menuItemTextures;

            this.minimizeSideMenuBar = new MinimizeSideMenuBar(this.mapArea, this.dicMenuItemTextures[typeof(MinimizeSideMenuBar)], Vector2.Zero);
            this.vBottomPositionOfMenuItems.X = this.minimizeSideMenuBar.Width;

            this.MapObjectsSideMenu = new SideMenu(this.mapArea, this.dicMenuItemTextures, this);
        }

        public SideMenu(MapArea mapArea, Dictionary<Type, Texture2D> menuItemTextures, SideMenu parentSideMenu)
        {
            this.mapArea = mapArea;
            this.dicMenuItemTextures = menuItemTextures;

            this.minimizeSideMenuBar = new MinimizeSideMenuBar(this.mapArea, this.dicMenuItemTextures[typeof(MinimizeSideMenuBar)], Vector2.Zero);
            this.vBottomPositionOfMenuItems.X = this.minimizeSideMenuBar.Width;

            this.ParentSideMenu = parentSideMenu;
        }

        public Viewport ResizeViewport(Viewport viewport)
        {
            if (!this.bMinimizing && !this.bMaxamizing)
            {
                this.sideMenuViewport = viewport;
                this.sideMenuViewport.Width = this.Width;
                this.sideMenuViewport.X = viewport.Width - this.Width;
                this.sideMenuViewport.Y = 0;

                viewport.Width -= this.Width;
            }
            else if(this.bMinimizing)
            {
                if (this.sideMenuViewport.Width - N_RESIZE_SPEED > this.minimizeSideMenuBar.Width)
                {
                    this.sideMenuViewport.Width -= N_RESIZE_SPEED;
                    this.sideMenuViewport.X += N_RESIZE_SPEED;
                    viewport.Width += N_RESIZE_SPEED;
                }
                else
                {
                    int nDiff = this.sideMenuViewport.Width - this.minimizeSideMenuBar.Width;
                    this.sideMenuViewport.Width -= nDiff;
                    this.sideMenuViewport.X += nDiff;
                    viewport.Width += nDiff;

                    this.bMinimizing = false;
                    this.bMinimized = true;
                }
            }
            else if (this.bMaxamizing)
            {
                if (this.sideMenuViewport.Width + N_RESIZE_SPEED < this.Width)
                {
                    this.sideMenuViewport.Width += N_RESIZE_SPEED;
                    this.sideMenuViewport.X -= N_RESIZE_SPEED;
                    viewport.Width -= N_RESIZE_SPEED;
                }
                else
                {
                    int nDiff = this.Width - this.sideMenuViewport.Width;
                    this.sideMenuViewport.Width += nDiff;
                    this.sideMenuViewport.X -= nDiff;
                    viewport.Width -= nDiff;

                    this.bMaxamizing = false;
                    this.bMinimized = false;
                }
            }
            return viewport;
        }

        public void Draw(SpriteBatch spriteBatch, GraphicsDevice graphicsDevice)
        {
            Viewport tempViewport = graphicsDevice.Viewport;

            graphicsDevice.Viewport = this.sideMenuViewport;
            graphicsDevice.Clear(this.cBackgroundColor);

            spriteBatch.Begin();
            this.minimizeSideMenuBar.Draw(spriteBatch);

            //Don't need to draw menu items when side menu minimized
            if (!this.bMinimized)
            {
                foreach (MenuItem item in this.lstMenuItems)
                {
                    item.Draw(spriteBatch);
                }
            }
            spriteBatch.End();

            graphicsDevice.Viewport = tempViewport;
        }

        public void AddMenuItem(Type MenuItemType)
        {
            Texture2D menuItemTexture = this.dicMenuItemTextures[MenuItemType];
            Vector2 vPosition = this.vBottomPositionOfMenuItems;
            this.vBottomPositionOfMenuItems.Y += menuItemTexture.Height;
            MenuItem newMenuItem = (MenuItem)MenuItemType.GetConstructor(new Type[] { typeof(MapArea), typeof(Texture2D), typeof(Vector2) }).Invoke(new object[] { this.mapArea, menuItemTexture, vPosition });
            this.lstMenuItems.Add(newMenuItem);
        }

        public void CheckItemClick(Vector2 vClickPosition)
        {
            foreach (MenuItem item in this.lstMenuItems)
            {
                if (item.CheckForMouseOver(vClickPosition))
                {
                    item.ClickAction();
                    return;
                }
            }

            if (this.minimizeSideMenuBar.CheckForMouseOver(vClickPosition))
            {
                if (!this.bMinimizing)
                {
                    this.minimizeSideMenuBar.ClickAction();
                }
            }
        }
    }
}
